import { IsNumber } from "../../../methods/judge";
import { RuleParse } from "../type";

const countRuleParse: RuleParse = {

	parseType: "count",

	isNested: false,

	preHandle: (parse, rule, char) => {
		const ruleSt = rule.select;
		const parseType = parse.top && parse.top.parseType;
		if (parseType === "globel") {
			if (char === "{") {
				const topRuleType = parse.pop().parseType;
				if (ruleSt === undefined) {
					throw new Error("栈列表选项为空");
				}
				else if (ruleSt.info.ruleData === undefined && ruleSt.children.length === 0) {
					throw new Error("限定个数项不能为空");
				}
				else if (ruleSt.info.range !== undefined) {
					throw new Error("不能重复限定个数");
				}
				else if (topRuleType === "switch") {
					throw new Error("字符组无法嵌套个数区间");
				}
				else if (topRuleType === "position") {
					throw new Error("定位无法嵌套个数区间");
				}
				ruleSt.info.range = { rangeType: "min", min: NaN, max: NaN };
				ruleSt.info.saveStr = "";
				parse.push(countRuleParse);
			} else if (char === "+") {
				if (ruleSt === undefined) {
					throw new Error("栈列表选项为空");
				}
				ruleSt.info.range = { rangeType: "max", min: 1, max: Infinity };
				parse.pop();
				parse.push(countRuleParse);
			} else if (char === "*") {
				if (ruleSt === undefined) {
					throw new Error("栈列表选项为空");
				}
				ruleSt.info.range = { rangeType: "max", min: 0, max: Infinity };
				parse.pop();
				parse.push(countRuleParse);
			} else if (char === "?") {
				if (ruleSt === undefined) {
					throw new Error("栈列表选项为空");
				}
				ruleSt.info.range = { rangeType: "max", min: 0, max: 1 };
				parse.pop();
				parse.push(countRuleParse);
			}
		}
	},

	judge: (parse, rule, char) => {
		return false;
	},

	// [canNested=true]
	handle: (parse, rule, char) => {
		const parseType = parse.top && parse.top.parseType;
		const ruleSt = rule.select;
		if (parseType === "count") {
			if (ruleSt === undefined) {
				throw new Error("栈列表选项为空");
			}
			if (ruleSt.info.saveStr === undefined) {
				rule.back();
				parse.pop();
				return true;
			} else if (char === "{" && ruleSt.info.saveStr === "") {
				return true;
			}
			const range = ruleSt.info.range;
			if (range === undefined) {
				throw new Error("限定个数无区间配置");
			}
			const { rangeType, min, max } = range;
			if (char === "}") {
				if (rangeType === "min") {
					if (min === undefined) {
						throw new Error("限定个数书写异常：无限定值");
					}
				} else if (rangeType === "max") {
					if (max !== undefined) {
						if (max < min) {
							throw new Error("限定个数书写异常：最大限定值不能小于最小限定值");
						}
					} else {
						throw new Error("限定个数书写异常：无最大限定值");
					}
				}
				rule.back();
				parse.pop();
			}
			else if (char === ",") {
				if (rangeType === "min") {
					if (min === undefined) {
						throw new Error("限定个数书写异常：不能直接接逗号");
					} else {
						ruleSt.info.saveStr = "";
						range.rangeType = "max";
						range.max = NaN;
					}
				} else {
					throw new Error("限定个数书写异常：max后面不能有逗号");
				}
			}
			else if (IsNumber(char)) {
				ruleSt.info.saveStr += char;
				if (rangeType === "min") {
					range.min = parseInt(ruleSt.info.saveStr);
					range.max = parseInt(ruleSt.info.saveStr);
				} else if (rangeType === "max") {
					range.max = parseInt(ruleSt.info.saveStr);
				}
			} else {
				throw new Error("限定个数书写异常");
			}
			return true;
		}
		return false;
	},
};

export default countRuleParse;
